#include "vi_stch_grp_imp.h"
#include "types.h"
#include "guard.h"
#include <stdio.h>

#include "mpi_vi.h"

using namespace Json;
using namespace detu_infra;

namespace detu_media
{
constexpr const VI_STITCH_GRP_ATTR_S ViStchGrpImp::defaultStchGrpAttr;

ViStchGrpImp::ViStchGrpImp(void)
	: ViStchGrp(), fInited(false), fStarted(false), fGrpId(-1), fMutex(MUTEX_RECURSIVE)
{
	memset(&fStchGrpAttr, 0, sizeof(VI_STITCH_GRP_ATTR_S));
}

ViStchGrpImp::~ViStchGrpImp(void)
{
	if (isInited())
		deinit();
}

S_Result ViStchGrpImp::start(void)
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	do
	{
		if (isStarted())
		{
			ret = S_OK;
			break;
		}

		if (!isInited())
		{
			printf("stitch group: %d not inited!\n", fGrpId);
			break;
		}

		ret = (HI_TRUE == fStchGrpAttr.bStitch) ? enable() : disable();

		fStarted = true;
	}
	while(0);

	return ret;
}


S_Result ViStchGrpImp::stop(void)
{
	Guard guard(fMutex);
	fStarted = false;

	return S_OK;
}

bool ViStchGrpImp::isStarted(void)
{
	return fStarted;
}

S_Result ViStchGrpImp::getId(int& id)
{
	id = fGrpId;
	
	return S_OK;
}

S_Result ViStchGrpImp::init(const Json::Value& config)
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	do
	{
		if (isInited())
			deinit();

		fInited = true;
		fStchGrpAttr = defaultStchGrpAttr;
		
		if (config.isMember("grpId") && config["grpId"].isIntegral())
			fGrpId = config["grpId"].asInt();

		if (config.isMember("grpAttr"))
		{
			const Value& grpAttr = config["grpAttr"];
			if (grpAttr.isMember("enabled") && grpAttr["enabled"].isBool() && grpAttr["enabled"].asBool())
				fStchGrpAttr.bStitch = grpAttr["enabled"].asBool() ? HI_TRUE : HI_FALSE;
			if (grpAttr.isMember("mode") && grpAttr["mode"].isString())
			{
				const Value& mode = grpAttr["mode"];
				if (0 == mode.asString().compare("sync"))
					fStchGrpAttr.enMode = VI_STITCH_ISP_CFG_SYNC;
				else if (0 == mode.asString().compare("normal"))
					fStchGrpAttr.enMode = VI_STITCH_ISP_CFG_NORMAL;
			}
			if (grpAttr.isMember("pipeNum") && grpAttr["pipeNum"].isIntegral())
				fStchGrpAttr.u32PipeNum = grpAttr["pipeNum"].asUInt();
			if (grpAttr.isMember("pipeId") && grpAttr["pipeId"].isArray())
				for (Uint32_t i = 0u; i < fStchGrpAttr.u32PipeNum && i < grpAttr["pipeId"].size(); i++)
				{
					if (grpAttr["pipeId"][i].isIntegral())
						fStchGrpAttr.PipeId[i] = grpAttr["pipeId"][i].asInt();
				}
		}

		ret = S_OK;
		
	}
	while(0);

	return ret;
}

S_Result ViStchGrpImp::deinit(void)
{
	Guard guard(fMutex);
	if (isStarted())
		stop();
	fGrpId = -1;
	memset(&fStchGrpAttr, 0, sizeof(VI_STITCH_GRP_ATTR_S));

	fInited = false;
	
	return S_OK;
}

bool ViStchGrpImp::isInited(void)
{
	return fInited;
}

S_Result ViStchGrpImp::enable(void)
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	
	do
	{
		if (isInited())
		{
			if (S_OK != disable())
			{
				break;
			}

			fStchGrpAttr.bStitch = HI_TRUE;//HI_TRUE HI_FALSE
			HI_S32 s32Ret = HI_MPI_VI_SetStitchGrpAttr(fGrpId, &fStchGrpAttr);
			if (HI_SUCCESS != s32Ret)
			{
				printf("HI_MPI_VI_SetStitchGrpAttr enable failed! ret: 0x%x, grpId: %d\n", s32Ret, fGrpId);
				break;
			}

			ret = S_OK;
		}
	}
	while(0);

	return ret;
}

S_Result ViStchGrpImp::disable(void)
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	
	do
	{
		if (isInited())
		{
			fStchGrpAttr.bStitch = HI_FALSE;
			HI_S32 s32Ret = HI_MPI_VI_SetStitchGrpAttr(fGrpId, &fStchGrpAttr);
			if (HI_SUCCESS != s32Ret)
			{
				printf("HI_MPI_VI_SetStitchGrpAttr disable failed! ret: 0x%x, grpId: %d\n", s32Ret, fGrpId);
				break;
			}

			ret = S_OK;
		}
	}
	while(0);

	return ret;
}

}
